//
//  XPRefreshControl.swift
//  下拉刷新实现原理
//
//  Created by 徐攀 on 16/5/17.
//  Copyright © 2016年 徐攀. All rights reserved.
//

import UIKit


/// 判断下拉刷新状态的枚举
enum RefreshState: Int {
    case Normal = 0     // 普通状态（临界点前）
    case Ready        // 就绪状态（临界点后，释放即可刷新状态）
    case Refreshing     // 正在刷新状态
}

class XPRefreshControl: UIControl {
    
    private var currentScrollView: UIScrollView?
    
    /// 下拉刷新控件高度
    private let refreshControlHeight: CGFloat = 44
    /// 释放刷新的临界值
    private var criticalValue: CGFloat = 0
    
    /// 菊花
    lazy var activityIndicatorView: UIActivityIndicatorView = {
       let view = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
        view.hidesWhenStopped = true
        return view
    }()
    
    /// 箭头
    lazy var accessoryView: UIImageView = {
        let accessoryView = UIImageView(image: UIImage(named: "arrow"))
        return accessoryView
    }()
    
    /// 提示文本
    lazy var accessoryLabel: UILabel = {
        let label = UILabel()
        label.text = "下拉刷新"
        label.font = UIFont.systemFontOfSize(14)
        label.textColor = UIColor.darkTextColor()
        return label
    }()
    
    // MARK: - 核心代码1：监听刷新状态的改变
    var refreshState: RefreshState = .Normal {
        didSet {
//            print(refreshState)
            // 判断状态
            switch refreshState {
                // 刷新状态
            case .Refreshing:
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.currentScrollView?.contentInset.top = -self.criticalValue
                })
                accessoryLabel.text = "加载中……"
                activityIndicatorView.startAnimating()
                
                /// UIControl与UIView的最大区别：UIControl能发送事件
                sendActionsForControlEvents(.ValueChanged)
                
                // 就绪状态
            case .Ready:
                accessoryLabel.text = "释放刷新"
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.accessoryView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI))
                })
                activityIndicatorView.stopAnimating()
                
                // 普通状态
            case .Normal:
                accessoryLabel.text = "下拉刷新"

                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.accessoryView.transform = CGAffineTransformIdentity
                    self.currentScrollView?.contentInset.top = 64
                })
                
                activityIndicatorView.stopAnimating()
            }
            
            accessoryView.hidden = activityIndicatorView.isAnimating()
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupSubviews()
        
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setupSubviews() {
        
        accessoryView.center = CGPointMake(UIScreen.mainScreen().bounds.size.width / 2 - 30, refreshControlHeight / 2)
        accessoryView.bounds = CGRectMake(0, 0, 10, 30)
        activityIndicatorView.center = accessoryView.center
        accessoryLabel.sizeToFit()
        accessoryLabel.frame.origin.x = CGRectGetMaxX(accessoryView.frame) + 10
        accessoryLabel.frame.origin.y = refreshControlHeight / 2 - accessoryLabel.bounds.size.height / 2
        
        addSubview(activityIndicatorView)
        addSubview(accessoryView)
        addSubview(accessoryLabel)
    }
    
    // MARK: - 控件添加到父控件时调用的方法
    override func willMoveToSuperview(newSuperview: UIView?) {
        
        if let tableView = newSuperview {
            
            refreshState = .Normal
            
            frame.size.width = tableView.bounds.size.width
            frame.size.height = refreshControlHeight
            frame.origin.y = -refreshControlHeight
            
            backgroundColor = UIColor(white: 0.95, alpha: 1.0)
            
            currentScrollView = tableView as? UIScrollView
            
            currentScrollView?.addObserver(self, forKeyPath: "contentOffset", options: .New, context: nil)
        }
    }
    // MARK: - KVO监听父控件的滚动
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        
        // 判断父控件是否为手动拖拽状态
        if currentScrollView!.dragging {
            // 计算临界值
            criticalValue = -(currentScrollView!.contentInset.top + refreshControlHeight)
            // 判断偏移量与临界值的关系
            if currentScrollView?.contentOffset.y < criticalValue && refreshState == .Normal {
                refreshState = .Ready
            }else if currentScrollView?.contentOffset.y >= criticalValue && refreshState == .Ready {
                refreshState = .Normal
            }
            // 拖拽释放后，如果是就绪状态，那么进入刷新状态
        }else {
            if refreshState == .Ready {
                refreshState = .Refreshing
            }
        }
    }
    
    // MARK: - 结束刷新时调用的方法
    func endRefreshing() {
        // 结束刷新，进入普通状态
        refreshState = .Normal
    }
    
    // MARK: - 移除KVO
    deinit {
        currentScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
}














